var Config = require('config');
var async = require('async');
var request = require('request');
var crypto = require('crypto');
const EventEmitter = require('events');
var emitter = new EventEmitter();
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var http = require('http').Server(app);
var io = require('socket.io-client');
var SerialPort = require('serialport');
var fs = require('fs');

var socket;
var sms_socket;
var port;
var ISSENDLOG = false;

app.use("/", express.static('public'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.use(function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Credentials', true);
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-type', 'Accept');
    res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
    next();
});

app.get('/', function (req, res) {
    res.redirect('configManage.html');
});

app.get('/getConfig', function (req, res) {
    var fs1 = require('fs');
    fs1.readFile('./config/default.json', function (err, data) {
        if (err) throw err;
        var config = JSON.parse(data)
        res.send(config)
    });
});
var postCpunt = 0;
app.post('/startUpStation', function (req, res) {
    if (!emitter) {
        emitter = new EventEmitter();
    }
    if (postCpunt == 0) {
        try {
            var startConfig = JSON.parse(JSON.stringify(Config));
            startConfig['station'].status = "start";
            Config = startConfig;
            fs.writeFile('./config/default.json', JSON.stringify(startConfig));
            startStation();
        }
        catch (err) {
            res.send(false)
        }
        postCpunt++;
    } else {
        res.send('option_item')
    }
});
app.post('/stopUp', function (req, res) {
    emitter = null;
    postCpunt = 0;
    if (port) {
        port.close(function () {
            console.log('串口关闭！')
        }, function (err) {
            console.log(err)
        });
    }
    if (socket) {
        socket.disconnect();
    }
    if (sms_socket) {
        sms_socket.disconnect();
    }
    var stopConfig = JSON.parse(JSON.stringify(Config));
    stopConfig['station'].status = "stop";
    Config = stopConfig
    fs.writeFile('./config/default.json', JSON.stringify(stopConfig));
    res.send(true);
});
app.post('/changeConfig', function (req, res) {
    var oldConfig = req.body;
    var stationStatus = JSON.parse(JSON.stringify(Config));
    oldConfig['station'].status = stationStatus['station'].status;
    oldConfig['position'] = stationStatus['position']
    oldConfig['position'].log_position = stationStatus['position'].log_position;
    oldConfig['position'].log_archive_position = stationStatus['position'].log_archive_position;
    Config = oldConfig;
    fs.writeFile('./config/default.json', JSON.stringify(oldConfig));
    res.send(true)
});

function init() {
    if (Config['station'].status == 'start') {
        startStation()
    }
}
init();

function startStation() {
    var queueConf = Config['socket'];
    var queueConfStation = Config['station']
    socket = io.connect('http://' + queueConf.server + ':' + queueConf.server_port, {query: "station=" + queueConfStation.id + ""});
    sms_socket = io.connect('http://' + queueConf.server + ':3332', {query: "station=" + queueConfStation.id + ""});
    var logger = require("./log4js")(Config['station'].id);
    emitterOn(queueConfStation);
    setupSerialPort(queueConf, queueConfStation, logger);
    setInterval(function () {
        sendLogFiles(queueConf);
    }, 1000 * 150);
    sendLogFiles(queueConf);
}
var logger = require("./log4js")(Config['station'].id);
function onRawData(data, queueConfStation, logger) {
    // TODO calculate the hash value of this package
    var pkg = {
        station: queueConfStation.id,
        data: data.toString('base64'),
        length: data.length,
        fetched_at: (new Date()).toISOString()
    };
    if (emitter) {
        logger.info(pkg);
        emitter.emit('new_pkg', pkg);
    }
}
function emitterOn(queueConfStation) {
    emitter.on('new_pkg', function (pkg) {
        socket.emit('' + queueConfStation.id, pkg);
        sms_socket.emit('' + queueConfStation.id, {status: "connect"});
        console.log('sent');
    });
}

function setupSerialPort(queueConf, queueConfStation, logger) {
    port = new SerialPort(Config['socket'].serial_port, {
        baudRate: Config['socket'].baudRate
    });
    port.on('open', function () {
        port.on('data', function (data) {
            onRawData(data, queueConfStation, logger);
        });
    });
    port.on('error', function (err) {
        console.log('Error: ', err.message);
    })
}
function sendLogFiles(queueConf) {
    var position = Config['position']
    var fsSend = require('fs')
    var gracefulFs = require('graceful-fs');
    gracefulFs.gracefulify(fsSend);
    var files = fsSend.readdirSync(position.log_position);

    async.eachSeries(files, function (filePath, callback) {

        if (filePath.endsWith(".log") || ISSENDLOG!==false) {
            return callback(null, null);
        }
        var path = position.log_position + filePath;
        var formData = {
            // log_file: fs.createReadStream('/Users/xiaopingfeng/projects/gnss/gnss_pipeline/station/logs/beijing-fxp.log-12-29-21-25'),
            log_file: fsSend.createReadStream(path)
            // TODO add md5 code to be sent to server
            // md5: crypto.md5()
        };
        ISSENDLOG = true;
        request.post({
            url: 'http://' + queueConf.server + ':' + queueConf.log_server_port + '/logs',
            formData: formData
        }, function optionalCallback(err, httpResponse, body) {
            ISSENDLOG = false;
            if (err) {
                callback(null, null);
                return console.error('upload failed:', err);
            }
            console.log('Upload successful!  Server responded with:', body);
            if (!fsSend.existsSync(position.log_archive_position)) {
                fsSend.mkdirSync(position.log_archive_position);
                fsSend.renameSync(path, position.log_archive_position + filePath);
            }
            else {
                fsSend.renameSync(path, position.log_archive_position + filePath);
            }
            callback(null, null);

        });
    }, function (err, results) {
        ISSENDLOG = false;
        // results now equals an array of the existing files
    });

}
http.listen(8899, function () {
    console.log(8899);
});
